package com.callbell.cas.handler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;

import org.apache.shiro.crypto.hash.Sha512Hash;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import com.callbell.cas.exception.LoginValidateException;
import com.callbell.cas.sdk.impl.LuosimaoSMS;
import com.callbell.cas.util.Digests;
import com.callbell.cas.util.Encodes;
import com.callbell.cas.util.SMSKit;
import com.google.code.kaptcha.Constants;

/**
 * 找回密码
 * @author xlh
 *
 *
 */
@SuppressWarnings("deprecation")
public class FindPasswordController extends AbstractController{
	
	private SimpleJdbcTemplate jdbcTemplate;
	
	private DataSource dataSource;
	
	private static final int HASH_INTERATIONS = 264544;

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String option = ServletRequestUtils.getStringParameter(request, "option");
		if("oneOpt".equals(option)){
			String service = ServletRequestUtils.getStringParameter(request, "service");
			request.getSession().setAttribute("retService", service);
			request.setAttribute("flag", "one");
		} else if("twoOpt".equals(option)){
			String mobilePhone = ServletRequestUtils.getStringParameter(request, "mobilePhone");
			if(!checkUser(mobilePhone)){
				sendMessage(request, mobilePhone);
				request.setAttribute("flag", "two");
				request.setAttribute("mobile", mobilePhone);
			} else {
				String retService = request.getSession().getAttribute("retService") + "";
				request.setAttribute("service", retService);
				request.setAttribute("flag", "userLock");
			}
		} else if("threeOpt".equals(option)){
			String mobilePhone = ServletRequestUtils.getStringParameter(request, "mobilePhone");
			request.getSession().removeAttribute("currentTime");
			request.getSession().removeAttribute("msgCode");
			request.setAttribute("mobile", mobilePhone);
			request.setAttribute("flag", "three");
		} else if("fourOpt".equals(option)){
			resetPassword(request);
			String retService = request.getSession().getAttribute("retService") + "";
			request.setAttribute("service", retService);
			request.getSession().removeAttribute("retService");
			request.setAttribute("flag", "four");
		} else if("checkCapt".equals(option)){//校验图形验证码
			boolean bln = isCapTextTrue(request);
			response.getWriter().println(bln);
			return null;
		} else if("sendMessage".equals(option)){//发送短信验证码
			String mobilePhone = ServletRequestUtils.getStringParameter(request, "mobilePhone");
			sendMessage(request, mobilePhone);
		} else if("checkCode".equals(option)){//校验验证码
			boolean bln = isMsgCodeTrue(request);
			response.getWriter().println(bln);
			return null;
		} else if("changePwd".equals(option)){//修改密码
			String mobilePhone = ServletRequestUtils.getStringParameter(request, "mobile");
			String service = ServletRequestUtils.getStringParameter(request, "service");
			request.getSession().setAttribute("retService", service);
			request.setAttribute("mobile", mobilePhone);
			request.setAttribute("flag", "change");
			return new ModelAndView("casChangePasswordView");
		} else if ("checkOldpwd".equals(option)){
			boolean bln = checkOldPwd(request);
			response.getWriter().println(bln);
			return null;
		} else if("commitChangePwd".equals(option)){//提交修改密码操作
			resetPassword(request);
			request.setAttribute("flag", "success");
			String retService = request.getSession().getAttribute("retService") + "";
			request.setAttribute("service", retService);
			request.getSession().removeAttribute("retService");
			return new ModelAndView("casChangePasswordView");
		}
		return new ModelAndView("casFindPasswordView");
	}
	
	private boolean isCapTextTrue(HttpServletRequest request) throws ServletRequestBindingException{
		String checkCode = ServletRequestUtils.getStringParameter(request, "verse_regis");//图形验证码
		String capText = request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY).toString();
		return checkCode.equalsIgnoreCase(capText) ? true : false;
	}
	
	private void sendMessage(HttpServletRequest request, String mobilePhone) throws ServletRequestBindingException{
		SMSKit.setSmsService(new LuosimaoSMS());
		String msgCode = SMSKit.sendRandomCheckCode(mobilePhone, "尊敬的用户");
		HttpSession session = request.getSession();
		session.setAttribute("currentTime", System.currentTimeMillis());
		session.setMaxInactiveInterval(1800);
		session.setAttribute("msgCode", msgCode);
	}
	
	private boolean isMsgCodeTrue(HttpServletRequest request) throws ServletRequestBindingException{
		String msgCode = ServletRequestUtils.getStringParameter(request, "msgCode");//短信验证码
		String code = request.getSession().getAttribute("msgCode")+"";
		if(code == null || "".equals(code) || !msgCode.equalsIgnoreCase(code)){
			return false;
		}
		String currentTime = request.getSession().getAttribute("currentTime") + "";
		long endTime = System.currentTimeMillis();
		if((endTime - (Long.parseLong(currentTime))) > 180000){
			return false;
		}
		return true;
	}
	
	private void resetPassword(HttpServletRequest request) throws ServletRequestBindingException{
		String mobilePhone = ServletRequestUtils.getStringParameter(request, "mobilePhone");//手机号码
		String password = ServletRequestUtils.getStringParameter(request, "pwd");// 密码
		
		byte[] bsalt = Digests.generateSalt(32);
		String salt = Encodes.encodeHex(bsalt);
		Sha512Hash sha = new Sha512Hash(password, bsalt, HASH_INTERATIONS);
		String saltPassword = sha.toHex();
		
		Map<String, Object> valueMap = new HashMap<String, Object>();
		valueMap.put("mobile", mobilePhone);
		valueMap.put("password", saltPassword);
		valueMap.put("salt", salt);
		valueMap.put("status", 1); //将账户置为激活状态
		
		jdbcTemplate.update("update user set password=:password, salt=:salt, status=:status where account=:mobile", valueMap);
	}
	
	private boolean checkOldPwd(HttpServletRequest request) throws Exception{
		String mobilePhone = ServletRequestUtils.getStringParameter(request, "mobile");//手机号码
		String password = ServletRequestUtils.getStringParameter(request, "oldpwd");// 旧密码
		
		boolean result = false;
		String querySQL = "select password, salt from user where account=?";
		List<Map<String,Object>> userList = jdbcTemplate.queryForList(querySQL, mobilePhone);
		Map<String,Object> userMap = null;
		if(userList.size() > 0){
			userMap = userList.get(0);
		}
		if(userMap == null){
			throw new LoginValidateException(LoginValidateException.NO_USER);
		}
		
		byte[] salt = Encodes.decodeHex(userMap.get("salt").toString());
		Sha512Hash sha = new Sha512Hash(password, salt, HASH_INTERATIONS);
		String encryptedPassword = sha.toHex();
		if(encryptedPassword.equals(userMap.get("password").toString())){
			result = true;
		}
		return result;
	}
	
	private boolean checkUser(String account) throws Exception {
		boolean result = false;
		String querySQL = "select status from user where account=?";
		List<Map<String,Object>> userList = jdbcTemplate.queryForList(querySQL, account);
		if(userList.size() > 0){
			Map<String,Object> userMap = userList.get(0);
			String status = userMap.get("status").toString();
			if("2".equals(status)){
				result = true;
			}
		}
		return result;
	}
	
	public void setDataSource(final DataSource dataSource) {
		this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
	}

	protected final DataSource getDataSource() {
		return this.dataSource;
	}
}
